﻿using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.DataAccess;
using Kiiro.ExceptionManagement;
using Kiiro.Model.TimerJobs;
using Kiiro.Validation.Validators.Entities;
using Kiiro.Model.Utility;

namespace Kiiro.Model
{
    public static class SetupModel
    {
        public static Setup GetMidoriSetup ( Guid siteCollectionId, string serverRelativeUrl )
        {
            Setup setup = null;
            object temp = CacheHelper.GetPortalCache(Constants.CacheKeys.Setup, siteCollectionId, serverRelativeUrl);

            if ( temp != null )
            {
                setup = ( Setup ) temp;
            }
            else
            {
                setup = SetupDA.Instance.GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
                CacheHelper.UpdatePortalCache(Constants.CacheKeys.Setup, setup, siteCollectionId, serverRelativeUrl);
            }

            return setup;
        }
        
        public static Setup GetKiiroSetupNoCache ( Guid siteCollectionId, string serverRelativeUrl )
        {
            return SetupDA.Instance.GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
        }

        /// <summary>
        /// Gets the SharePoint System Email Address starting with the current Web Application, else the Farm if it is not set
        /// </summary>
        public static void GetSharePointOutgoingEmailSettings ( Guid siteCollectionId, string serverRelativeUrl, out string replyToEmailAddress, out string smtpServer )
        {
            replyToEmailAddress = default ( string );
            smtpServer = default ( string );

            string webAppUrl = default ( string );
            SPWebApplication webApp = null;

            try
            {
                // use current web app settings
                using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
                {
                    webAppUrl = web.Url;
                }

                if ( !string.IsNullOrEmpty ( webAppUrl ) )
                {
                    webApp = SPWebApplication.Lookup ( new Uri ( webAppUrl ) );

                    if ( webApp != null )
                    {
                        if ( string.IsNullOrEmpty ( replyToEmailAddress ) )
                        {
                            if ( !string.IsNullOrEmpty ( webApp.OutboundMailReplyToAddress ) )
                                replyToEmailAddress = webApp.OutboundMailReplyToAddress;
                            else
                                replyToEmailAddress = webApp.OutboundMailSenderAddress;
                        }

                        if ( string.IsNullOrEmpty ( smtpServer ) )
                        {
                            if ( webApp.OutboundMailServiceInstance != null && webApp.OutboundMailServiceInstance.Server != null )
                            {
                                if ( !string.IsNullOrEmpty ( webApp.OutboundMailServiceInstance.Server.Address ) )
                                    smtpServer = webApp.OutboundMailServiceInstance.Server.Address;
                            }
                        }
                    }

                    // if web app does not have settings use farm settings
                    SPAdministrationWebApplication spAdminWebApp = SPAdministrationWebApplication.Local;

                    if ( string.IsNullOrEmpty ( replyToEmailAddress ) )
                    {
                        if ( !string.IsNullOrEmpty ( spAdminWebApp.OutboundMailReplyToAddress ) )
                            replyToEmailAddress = spAdminWebApp.OutboundMailReplyToAddress;
                        else
                            replyToEmailAddress = spAdminWebApp.OutboundMailSenderAddress;
                    }

                    if ( string.IsNullOrEmpty ( smtpServer ) )
                    {
                        if ( spAdminWebApp.OutboundMailServiceInstance != null && spAdminWebApp.OutboundMailServiceInstance.Server != null )
                        {
                            if ( !string.IsNullOrEmpty ( spAdminWebApp.OutboundMailServiceInstance.Server.Address ) )
                                smtpServer = spAdminWebApp.OutboundMailServiceInstance.Server.Address;
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }
            finally
            {
                if ( webApp != null ) webApp = null;
            }
        }

        /// <summary>
        /// Get SMTPServerExists
        /// </summary>
        public static bool GetSMTPServerExists ( Guid siteCollectionId, string serverRelativeUrl )
        {
            bool smtpServerExists = false;

            Setup setup = GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
            if ( setup != null )
            {
                smtpServerExists = setup.SendEmailUpdates && !string.IsNullOrEmpty ( setup.EmailFromAddress ) && !string.IsNullOrEmpty ( setup.SMTPInfo );
            }

            return smtpServerExists;
        }

        /// <summary>
        /// Get the Title for display in the header
        /// </summary>
        public static string GetTitle ( Guid siteCollectionId, string serverRelativeUrl )
        {
            string title = "";
            object temp = null;

            if ( SPHelpers.IsPortal ( siteCollectionId, serverRelativeUrl ) )
            {
                temp = CacheHelper.GetPortalCache(Constants.CacheKeys.Title, siteCollectionId, serverRelativeUrl);
                if ( temp != null )
                {
                    title = ( string ) temp;
                }
                else
                {
                    Setup setup = GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
                    if ( setup != null && !string.IsNullOrEmpty(setup.SiteName) )
                    {
                        title = setup.SiteName;
                        CacheHelper.UpdatePortalCache ( Constants.CacheKeys.Title, title, siteCollectionId, serverRelativeUrl );
                    }
                    else
                    {
                        title = SPHelpers.GetWebTitle ( siteCollectionId, serverRelativeUrl );
                        CacheHelper.UpdatePortalCache(Constants.CacheKeys.Title, title, siteCollectionId, serverRelativeUrl);
                    }
                }
            }
            else
            {
                temp = CacheHelper.GetCache(Constants.CacheKeys.Title, siteCollectionId, serverRelativeUrl);
                if ( temp != null )
                {
                    title = ( string ) temp;
                }
                else
                {
                    Project project = ProjectsModel.GetByServerRelativeWebUrl ( siteCollectionId, serverRelativeUrl );
                    if ( project != null )
                    {
                        title = project.Title;
                        CacheHelper.UpdateCache(Constants.CacheKeys.Title, title, siteCollectionId, serverRelativeUrl);
                    }
                }
            }

            return title;
        }

        /// <summary>
        /// Gets the Logo url 
        /// </summary>
        public static string GetLogo ( Guid siteCollectionId, string serverRelativeUrl )
        {
            string logo = "";

            Setup setup = GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
            if ( setup != null )
            {
                logo = setup.LogoUrl;
            }

            return logo;
        }

        /// <summary>
        /// Gets the web part sandbox navigation text
        /// </summary>
        public static string GetWPSandboxNavText ( Guid siteCollectionId, string serverRelativeUrl )
        {
            string navText = "";

            Setup setup = GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
            if ( setup != null )
            {
                navText = setup.WPSandboxNavText;
            }

            return navText;
        }

        public static bool IsWPSandboxActivated ( Guid siteCollectionId, string serverRelativeUrl )
        {
            bool isWPSandboxActivated = false;

            Setup setup = GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
            if ( setup != null )
            {
                isWPSandboxActivated = setup.IsWPSandboxActivated;
            }

            return isWPSandboxActivated;
        }

        /// <summary>
        /// Gets the hours per day
        /// </summary>
        public static double GetHoursPerDay ( Guid siteCollectionId, string serverRelativeUrl )
        {
            double hours = 8;

            Setup setup = GetMidoriSetup ( siteCollectionId, serverRelativeUrl );
            if ( setup != null )
            {
                hours = setup.HoursPerDay;
            }

            return hours;
        }

        /// <summary>
        /// Save the SetupEntity
        /// </summary>
        public static Setup Save ( Setup setup, Guid siteCollectionId, string serverRelativeUrl )
        {
            try
            {
                if ( setup != null && setup.EditType != EditType.Unchanged )
                {
                    PermissionsModel.GetGlobalPermissionBitsForCurrentUser ( setup, setup.ModifiedBy, siteCollectionId, serverRelativeUrl, true );

                    if ( ( setup.EditType == EditType.Created && setup.PermissionBitsSetup [ 0 ] ) ||
                        ( setup.EditType == EditType.Updated && setup.PermissionBitsSetup [ 2 ] ) )
                    {
                        // need to reset messages to prevent duplicates created during validation of new key
                        setup.ClearValidationMessages ( );

                        // validate setup
                        new SetupValidator ( ).Validate ( setup );

                        // validate license keys
                        bool isValid = LicensingModel.ValidateLicenseKeys ( setup, siteCollectionId, serverRelativeUrl );

                        if ( setup.IsValid ( ) && isValid )
                        {
                            // save setup
                            setup = SetupDA.Instance.Save ( setup, siteCollectionId, serverRelativeUrl );

                            // Update cached values
                            CacheHelper.UpdatePortalCache(Constants.CacheKeys.Setup, setup, siteCollectionId, serverRelativeUrl);
                            CacheHelper.UpdatePortalCache(Constants.CacheKeys.Title, setup.SiteName, siteCollectionId, serverRelativeUrl);

                            KiiroSolutionControllerHelpers.EnsureSetup ( siteCollectionId, serverRelativeUrl );
                        }
                        else
                        {
                            if ( setup.LicenseKeyErrorMessages.Count > 0 )
                            {
                                foreach ( string message in setup.LicenseKeyErrorMessages )
                                {
                                    setup.LicenseKeyMessage.Add ( new ValidationMessage ( ValidationSeverity.Critical, message ) );
                                }
                            }
                        }
                    }
                    else
                        throw new KiiroUnauthorizedAccessException ( "Updating Setup Failed: Access Denied." );
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return setup;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Model/SetupModel.cs $
 * 
 * 18    26/11/09 10:02a Camerons
 * 
 * 17    21/10/09 3:06p Shafia
 * using CacheKeys constants instead of hard coding key names
 * 
 * 16    8/09/09 10:51a Camerons
 * Moved KiiroSolutionControllerHelpers to the Kiiro.Model.Utility
 * namespace
 * 
 * 15    4/09/09 3:18p Camerons
 * 
 * 14    1/09/09 3:09p Camerons
 * 
 * 13    8/31/09 3:36p Stefanf
 * 
 * 12    17/08/09 10:29a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/